﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HtmlAgilityPack;
using System.Web;
using DataWinner.Nba.Model;
using System.Data.Entity;
using EntityFramework.Extensions;
using JJY.Common;
using DataWinner.Nba.DataAccess.Sina;
using DataWinner.Entity.Nba_Sina.Models;

namespace DataWinner.Business.Manage
{
    public class SinaSpider
    {
        private const string DOMAINNAME = "http://nba.sports.sina.com.cn/";


        public static int ReadMatchList(string address, DateTime? fetchDate)
        {
            int result = 0;

            string strMatchList =
                HttpUtility.HtmlDecode(HttpRequestHelper.GetHtmlSourceByUrl(address, Encoding.Default)
                .HtmlToString().Trim());
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(strMatchList);

            string matchYear = doc.DocumentNode.SelectNodes(@"//strong")[0].InnerText.Substring(0, 4);
            string matchDate = string.Empty;

            HtmlNodeCollection nodeMatchList =
                doc.DocumentNode.SelectNodes(@"//div[@id='table980middle']/div/table/tr");

            Dictionary<string, int> dicUrl = new Dictionary<string, int>();

            if (nodeMatchList != null)
            {
                foreach (HtmlNode htmlNode in nodeMatchList)
                {
                    HtmlNodeCollection htmlNodeTdSet = doc.DocumentNode.SelectNodes(htmlNode.XPath + "/td");

                    if (htmlNodeTdSet.Count == 12)
                    {
                        if (htmlNodeTdSet[0].InnerText.IndexOf("星期") > -1)
                        {
                            matchDate = matchYear + "-" +
                                htmlNodeTdSet[0].InnerText.Substring(0, 6).Replace("月", "-").Replace("日", string.Empty);
                            if (int.Parse(htmlNodeTdSet[0].InnerText.Substring(0, 2)) < 9)
                            {
                                matchDate = (int.Parse(matchYear) + 1).ToString() + "-" +
                                    htmlNodeTdSet[0].InnerText.Substring(0, 6).Replace("月", "-").Replace("日", string.Empty);
                            }
                        }
                        else
                        {
                            string matchDateTime = matchDate + " " + htmlNodeTdSet[0].InnerText.Substring(0, 5) + ":00";
                            short matchType = 0;
                            if (htmlNodeTdSet[1].InnerText.IndexOf("季前赛") > -1)
                            {
                                matchType = 1;
                            }
                            else if (htmlNodeTdSet[1].InnerText.IndexOf("常规赛") > -1)
                            {
                                matchType = 2;
                            }
                            else if (htmlNodeTdSet[1].InnerText.IndexOf("季后赛") > -1)
                            {
                                matchType = 3;
                            }

                            string url = doc.DocumentNode.SelectNodes(htmlNodeTdSet[8].XPath + "/a")[0].Attributes["href"].Value;
                            if (!dicUrl.ContainsKey(url))
                            {
                                DateTime tempMatchDateTime = new DateTime();
                                if (DateTime.TryParse(matchDateTime, out tempMatchDateTime))
                                {
                                    if (fetchDate == null || (fetchDate != null && fetchDate.Value.Date == tempMatchDateTime.Date))
                                    {
                                        ReadMatch(DOMAINNAME + url, tempMatchDateTime, matchType);
                                        dicUrl.Add(url, 1);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return result;
        }

        private static bool ReadMatch(string urlMatch, DateTime matchDateTime, short matchType)
        {
            bool result = false;

            string strMatchInfo = HttpUtility.HtmlDecode(HttpRequestHelper.GetHtmlSourceByUrl(urlMatch,
                Encoding.Default).HtmlToString().Trim());

            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(strMatchInfo);

            Match_Sina match = new Match_Sina();
            TeamStat_Sina homeTeamStat = new TeamStat_Sina();
            TeamStat_Sina visitingTeamStat = new TeamStat_Sina();
            TeamStatDaily_Sina homeTeamStatDaily = new TeamStatDaily_Sina();
            TeamStatDaily_Sina homeOppoTeamStatDaily = new TeamStatDaily_Sina();
            TeamStatDaily_Sina visitingTeamStatDaily = new TeamStatDaily_Sina();
            TeamStatDaily_Sina visitingOppoTeamStatDaily = new TeamStatDaily_Sina();

            ReadTeamDataBasic(doc, matchDateTime, matchType, out match, out homeTeamStat, out visitingTeamStat);
            ReadTeamDataDetails(doc, match, homeTeamStat, visitingTeamStat);

            DaMatch daMatch = new DaMatch();
            DaTeamStat daTeamStat = new DaTeamStat();
            DaTeamStatDaily daTeamStatDaily = new DaTeamStatDaily();

            daMatch.AddOrModify(match);
            match.MatchId = daMatch.CreateMatchId(match);


            homeTeamStat.MatchId = match.MatchId;
            visitingTeamStat.MatchId = match.MatchId;
            daTeamStat.AddOrModify(homeTeamStat, visitingTeamStat);

            //***********************************************************************
            //StatType: 1:as home team; 2: opposite when as home team; 3: as visiting team; 4: opposite when as visiting team;
            //5: all team self; 6: all team opposite
            homeTeamStatDaily.TeamId = match.HomeTeamId;
            homeTeamStatDaily.MatchDate = match.MatchTime.Date;
            homeTeamStatDaily.StatType = 1;
            homeTeamStatDaily.TeamStatId = homeTeamStat.TeamStatId;

            homeOppoTeamStatDaily.TeamId = match.HomeTeamId;
            homeOppoTeamStatDaily.MatchDate = match.MatchTime.Date;
            homeOppoTeamStatDaily.StatType = 2;
            homeOppoTeamStatDaily.TeamStatId = visitingTeamStat.TeamStatId;

            visitingTeamStatDaily.TeamId = match.VisitingTeamId;
            visitingTeamStatDaily.MatchDate = match.MatchTime.Date;
            visitingTeamStatDaily.StatType = 3;
            visitingTeamStatDaily.TeamStatId = visitingTeamStat.TeamStatId;

            visitingOppoTeamStatDaily.TeamId = match.VisitingTeamId;
            visitingOppoTeamStatDaily.MatchDate = match.MatchTime.Date;
            visitingOppoTeamStatDaily.StatType = 4;
            visitingOppoTeamStatDaily.TeamStatId = homeTeamStat.TeamStatId;
            //***********************************************************************

            daTeamStatDaily.AddOrModify(homeTeamStatDaily, homeOppoTeamStatDaily, visitingTeamStatDaily, visitingOppoTeamStatDaily);

            result = true;
            return result;
        }

        private static bool ReadTeamDataBasic(HtmlDocument doc, DateTime matchDateTime, short matchType, out Match_Sina match,
            out TeamStat_Sina homeTeamStat, out TeamStat_Sina visitingTeamStat)
        {
            bool result = false;

            HtmlNodeCollection nodeTeamNameSet = doc.DocumentNode.SelectNodes("//a[@class='tlogo']");
            HtmlNodeCollection nodeTeamScore = doc.DocumentNode.SelectNodes("//td[@class='num']");

            Team_Sina visitingTeam = new Team_Sina()
            {
                TeamName = nodeTeamNameSet[0].InnerText.Trim()
            };

            Team_Sina homeTeam = new Team_Sina()
            {
                TeamName = nodeTeamNameSet[1].InnerText.Trim()
            };

            DaTeam daTeam = new DaTeam();
            daTeam.AddOrModify(homeTeam, visitingTeam);


            HtmlNode nodeScoreTable = doc.DocumentNode.SelectSingleNode("//table[@class='score']");
            HtmlNodeCollection nodeVisitingScore = doc.DocumentNode.SelectNodes(nodeScoreTable.XPath + "/tr[2]/td");
            HtmlNodeCollection nodeHomeScore = doc.DocumentNode.SelectNodes(nodeScoreTable.XPath + "/tr[3]/td");

            match = new Match_Sina()
            {
                Type = matchType,
                MatchTime = matchDateTime,
                HomeTeamId = homeTeam.TeamId,
                VisitingTeamId = visitingTeam.TeamId,
                SeasonYear = matchDateTime.Year
            };

            homeTeamStat = new TeamStat_Sina()
            {
                TeamId = homeTeam.TeamId,
                First = short.Parse(nodeHomeScore[0].InnerText),
                Second = short.Parse(nodeHomeScore[1].InnerText),
                Third = short.Parse(nodeHomeScore[2].InnerText),
                Fourth = short.Parse(nodeHomeScore[3].InnerText),
                Scoring = short.Parse(nodeTeamScore[1].InnerText)
            };

            visitingTeamStat = new TeamStat_Sina()
            {
                TeamId = visitingTeam.TeamId,
                First = short.Parse(nodeVisitingScore[0].InnerText),
                Second = short.Parse(nodeVisitingScore[1].InnerText),
                Third = short.Parse(nodeVisitingScore[2].InnerText),
                Fourth = short.Parse(nodeVisitingScore[3].InnerText),
                Scoring = short.Parse(nodeTeamScore[0].InnerText)
            };

            if (nodeVisitingScore.Count > 4)
            {
                short visitingOtSum = 0;
                short homeOtSum = 0;

                for (int i = 4; i < nodeVisitingScore.Count; i++)
                {
                    visitingOtSum += short.Parse(nodeVisitingScore[i].InnerText);
                    homeOtSum += short.Parse(nodeHomeScore[i].InnerText);
                }

                homeTeamStat.Ot1 = nodeHomeScore.Count >= 5 ? short.Parse(nodeHomeScore[4].InnerText) : (short)0;
                homeTeamStat.Ot2 = nodeHomeScore.Count >= 6 ? short.Parse(nodeHomeScore[5].InnerText) : (short)0;
                homeTeamStat.Ot3 = nodeHomeScore.Count >= 7 ? short.Parse(nodeHomeScore[6].InnerText) : (short)0;
                homeTeamStat.OtSum = homeOtSum;

                visitingTeamStat.Ot1 = nodeVisitingScore.Count >= 5 ? short.Parse(nodeVisitingScore[4].InnerText) : (short)0;
                visitingTeamStat.Ot2 = nodeVisitingScore.Count >= 6 ? short.Parse(nodeVisitingScore[5].InnerText) : (short)0;
                visitingTeamStat.Ot3 = nodeVisitingScore.Count >= 7 ? short.Parse(nodeVisitingScore[6].InnerText) : (short)0;
                visitingTeamStat.OtSum = visitingOtSum;
            }

            result = true;

            return result;
        }

        /*
        private static bool ReadTeamAndMemberDataDetails(HtmlDocument doc, Guid matchId, Guid visitingTeamId,
            Guid homeTeamId)
        {
            bool result = false;

            #region html repair
            string docTemp = doc.DocumentNode.SelectSingleNode("//div[@id='main']/div")
                .InnerHtml.HtmlToString().Replace("</td><tr", "</td></tr><tr");
            while (docTemp.IndexOf("</tr></tr>") > -1)
            {
                docTemp = docTemp.Replace("</tr></tr>", "</tr>");
            }
            doc.LoadHtml(docTemp);
            #endregion

            //HtmlNodeCollection nodeTableDetails = doc.DocumentNode.SelectNodes("//table");

            MatchTeamData visitingMatchTeamData = new MatchTeamData();
            MatchTeamData homeMatchTeamData = new MatchTeamData();


            HtmlNodeCollection nodeVisitingDetails =
                doc.DocumentNode.SelectNodes("table[2]/tr[2]/td/table/tr");
            HtmlNodeCollection nodeHomeDetails =
                doc.DocumentNode.SelectNodes("table[3]/tr[2]/td/table/tr");

            visitingMatchTeamData.MatchId = matchId;
            visitingMatchTeamData.TeamId = visitingTeamId;
            homeMatchTeamData.MatchId = matchId;
            homeMatchTeamData.TeamId = homeTeamId;
            if (int.Parse(nodeVisitingDetails[1].InnerText.Trim()) > 0 && nodeVisitingDetails.Count > 0)
            {
                short visitingTotalShot =
                    short.Parse(nodeVisitingDetails[2].InnerText.Split('-')[1].Trim());
                short visitingTotalGoal =
                    short.Parse(nodeVisitingDetails[2].InnerText.Split('-')[0].Trim());
                short visitingShot3 =
                    short.Parse(nodeVisitingDetails[3].InnerText.Split('-')[1].Trim());
                short visitingShot3Goal =
                    short.Parse(nodeVisitingDetails[3].InnerText.Split('-')[0].Trim());
                short visitingFreeThrow =
                    short.Parse(nodeVisitingDetails[4].InnerText.Split('-')[1].Trim());
                short visitingFreeThrowGoal =
                    short.Parse(nodeVisitingDetails[4].InnerText.Split('-')[0].Trim());
                visitingMatchTeamData.Shot3 = visitingShot3;
                visitingMatchTeamData.Goal3 = visitingShot3Goal;
                visitingMatchTeamData.Shot2 = (short)(visitingTotalShot - visitingShot3);
                visitingMatchTeamData.Goal2 = (short)(visitingTotalGoal - visitingShot3Goal);
                visitingMatchTeamData.FreeThrow = visitingFreeThrow;
                visitingMatchTeamData.FreeThrowGoal = visitingFreeThrowGoal;
                visitingMatchTeamData.OffensiveRebound = short.Parse(nodeVisitingDetails[5].InnerText.Trim());
                visitingMatchTeamData.DefensiveRebound = short.Parse(nodeVisitingDetails[6].InnerText.Trim());
                visitingMatchTeamData.Assist = short.Parse(nodeVisitingDetails[8].InnerText.Trim());
                visitingMatchTeamData.Steal = short.Parse(nodeVisitingDetails[9].InnerText.Trim());
                visitingMatchTeamData.Block = short.Parse(nodeVisitingDetails[10].InnerText.Trim());
                visitingMatchTeamData.Turnover = short.Parse(nodeVisitingDetails[11].InnerText.Trim());
                visitingMatchTeamData.Foul = short.Parse(nodeVisitingDetails[12].InnerText.Trim());
                visitingMatchTeamData.Scoring = short.Parse(nodeVisitingDetails[13].InnerText.Trim());

                short homeTotalShot =
                    short.Parse(nodeHomeDetails[2].InnerText.Split('-')[1].Trim());
                short homeTotalGoal =
                    short.Parse(nodeHomeDetails[2].InnerText.Split('-')[0].Trim());
                short homeShot3 =
                    short.Parse(nodeHomeDetails[3].InnerText.Split('-')[1].Trim());
                short homeShot3Goal =
                    short.Parse(nodeHomeDetails[3].InnerText.Split('-')[0].Trim());
                short homeFreeThrow =
                    short.Parse(nodeHomeDetails[4].InnerText.Split('-')[1].Trim());
                short homeFreeThrowGoal =
                    short.Parse(nodeHomeDetails[4].InnerText.Split('-')[0].Trim());
                homeMatchTeamData.Shot3 = homeShot3;
                homeMatchTeamData.Goal3 = homeShot3Goal;
                homeMatchTeamData.Shot2 = (short)(homeTotalShot - homeShot3);
                homeMatchTeamData.Goal2 = (short)(homeTotalGoal - homeShot3Goal);
                homeMatchTeamData.FreeThrow = homeFreeThrow;
                homeMatchTeamData.FreeThrowGoal = homeFreeThrowGoal;
                homeMatchTeamData.OffensiveRebound = short.Parse(nodeHomeDetails[5].InnerText.Trim());
                homeMatchTeamData.DefensiveRebound = short.Parse(nodeHomeDetails[6].InnerText.Trim());
                homeMatchTeamData.Assist = short.Parse(nodeHomeDetails[8].InnerText.Trim());
                homeMatchTeamData.Steal = short.Parse(nodeHomeDetails[9].InnerText.Trim());
                homeMatchTeamData.Block = short.Parse(nodeHomeDetails[10].InnerText.Trim());
                homeMatchTeamData.Turnover = short.Parse(nodeHomeDetails[11].InnerText.Trim());
                homeMatchTeamData.Foul = short.Parse(nodeHomeDetails[12].InnerText.Trim());
                homeMatchTeamData.Scoring = short.Parse(nodeHomeDetails[13].InnerText.Trim());
            }

            if (daMatchTeamData.InsertOrUpdate(visitingMatchTeamData) > 0
                && daMatchTeamData.InsertOrUpdate(homeMatchTeamData) > 0)
            {
                result = true;
            }

            return result;
        }

        private static bool ReadMemberDetails(HtmlNodeCollection htmlNodeTrSet, int isVisiting)
        {
            bool result = false;

            foreach (HtmlNode htmlNodeTr in htmlNodeTrSet)
            {
                HtmlNodeCollection htmlNodeTdSet = htmlNodeTr.SelectNodes("/td");
                int isRotation = 0;
                if (htmlNodeTdSet.Count == 14)
                {
                    if (htmlNodeTdSet[0].InnerText.Trim() == "首发球员")
                    {
                        isRotation = 1;
                    }
                    else if (htmlNodeTdSet[0].InnerText.Trim() == "替补球员")
                    {
                        isRotation = 0;
                    }
                    else if (htmlNodeTdSet[0].InnerText.Trim() == "总计")
                    {

                    }
                    else
                    {

                    }
                }
                else if (htmlNodeTdSet.Count == 2)
                {

                }
            }
            return result;
        }*/

        [Obsolete]
        private static bool ReadTeamDataDetails(HtmlDocument doc, Match_Sina match, TeamStat_Sina homeTeamStat,
            TeamStat_Sina visitingTeamStat)
        {
            bool result = false;

            #region html repair
            string docTemp = doc.DocumentNode.SelectSingleNode("//div[@id='main']/div")
                .InnerHtml.HtmlToString().Replace("</td><tr", "</td></tr><tr");
            while (docTemp.IndexOf("</tr></tr>") > -1)
            {
                docTemp = docTemp.Replace("</tr></tr>", "</tr>");
            }
            doc.LoadHtml(docTemp);
            #endregion

            //HtmlNodeCollection nodeTableDetails = doc.DocumentNode.SelectNodes("//table");


            HtmlNodeCollection nodeVisitingDetails =
                doc.DocumentNode.SelectNodes("table[2]/tr[2]/td/table/tr[last()]/td");
            HtmlNodeCollection nodeHomeDetails =
                doc.DocumentNode.SelectNodes("table[3]/tr[2]/td/table/tr[last()]/td");

            visitingTeamStat.MatchId = match.MatchId;
            visitingTeamStat.TeamId = visitingTeamStat.TeamId;
            homeTeamStat.MatchId = match.MatchId;
            homeTeamStat.TeamId = homeTeamStat.TeamId;

            if (int.Parse(nodeVisitingDetails[1].InnerText.Trim()) > 0 && nodeVisitingDetails.Count > 0)
            {
                short visitingTotalShot =
                    short.Parse(nodeVisitingDetails[2].InnerText.Split('-')[1].Trim());
                short visitingTotalGoal =
                    short.Parse(nodeVisitingDetails[2].InnerText.Split('-')[0].Trim());
                short visitingShot3 =
                    short.Parse(nodeVisitingDetails[3].InnerText.Split('-')[1].Trim());
                short visitingShot3Goal =
                    short.Parse(nodeVisitingDetails[3].InnerText.Split('-')[0].Trim());
                short visitingFreeThrow =
                    short.Parse(nodeVisitingDetails[4].InnerText.Split('-')[1].Trim());
                short visitingFreeThrowGoal =
                    short.Parse(nodeVisitingDetails[4].InnerText.Split('-')[0].Trim());
                visitingTeamStat.Shot3 = visitingShot3;
                visitingTeamStat.Goal3 = visitingShot3Goal;
                visitingTeamStat.Shot2 = (short)(visitingTotalShot - visitingShot3);
                visitingTeamStat.Goal2 = (short)(visitingTotalGoal - visitingShot3Goal);
                visitingTeamStat.FreeThrow = visitingFreeThrow;
                visitingTeamStat.FreeThrowGoal = visitingFreeThrowGoal;
                visitingTeamStat.OffensiveRebound = short.Parse(nodeVisitingDetails[5].InnerText.Trim());
                visitingTeamStat.DefensiveRebound = short.Parse(nodeVisitingDetails[6].InnerText.Trim());
                visitingTeamStat.Assist = short.Parse(nodeVisitingDetails[8].InnerText.Trim());
                visitingTeamStat.Steal = short.Parse(nodeVisitingDetails[9].InnerText.Trim());
                visitingTeamStat.Block = short.Parse(nodeVisitingDetails[10].InnerText.Trim());
                visitingTeamStat.Turnover = short.Parse(nodeVisitingDetails[11].InnerText.Trim());
                visitingTeamStat.Foul = short.Parse(nodeVisitingDetails[12].InnerText.Trim());
                visitingTeamStat.Scoring = short.Parse(nodeVisitingDetails[13].InnerText.Trim());

                short homeTotalShot =
                    short.Parse(nodeHomeDetails[2].InnerText.Split('-')[1].Trim());
                short homeTotalGoal =
                    short.Parse(nodeHomeDetails[2].InnerText.Split('-')[0].Trim());
                short homeShot3 =
                    short.Parse(nodeHomeDetails[3].InnerText.Split('-')[1].Trim());
                short homeShot3Goal =
                    short.Parse(nodeHomeDetails[3].InnerText.Split('-')[0].Trim());
                short homeFreeThrow =
                    short.Parse(nodeHomeDetails[4].InnerText.Split('-')[1].Trim());
                short homeFreeThrowGoal =
                    short.Parse(nodeHomeDetails[4].InnerText.Split('-')[0].Trim());
                homeTeamStat.Shot3 = homeShot3;
                homeTeamStat.Goal3 = homeShot3Goal;
                homeTeamStat.Shot2 = (short)(homeTotalShot - homeShot3);
                homeTeamStat.Goal2 = (short)(homeTotalGoal - homeShot3Goal);
                homeTeamStat.FreeThrow = homeFreeThrow;
                homeTeamStat.FreeThrowGoal = homeFreeThrowGoal;
                homeTeamStat.OffensiveRebound = short.Parse(nodeHomeDetails[5].InnerText.Trim());
                homeTeamStat.DefensiveRebound = short.Parse(nodeHomeDetails[6].InnerText.Trim());
                homeTeamStat.Assist = short.Parse(nodeHomeDetails[8].InnerText.Trim());
                homeTeamStat.Steal = short.Parse(nodeHomeDetails[9].InnerText.Trim());
                homeTeamStat.Block = short.Parse(nodeHomeDetails[10].InnerText.Trim());
                homeTeamStat.Turnover = short.Parse(nodeHomeDetails[11].InnerText.Trim());
                homeTeamStat.Foul = short.Parse(nodeHomeDetails[12].InnerText.Trim());
                homeTeamStat.Scoring = short.Parse(nodeHomeDetails[13].InnerText.Trim());

                result = true;
            }

            return result;
        }
    }
}
